#include "util.h"

#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>

#define LOG_MAX_LEN 2048
// 读取文件
char *__read_file(const char *filename)
{
    FILE *file;
    size_t file_len;
    char *data;
	
    file = fopen(filename, "r");
    if (file == NULL) {
        printf("Open File %s Error: %s\n", filename, strerror(errno));
        return NULL;
    }
    
    fseek(file, 0, SEEK_END);
    file_len = ftell(file);
    fseek(file, 0, SEEK_SET);

	data = (char *)malloc(file_len + 1); // file_len + '\0'
    if (data == NULL) {
        printf("Malloc(%lu) Error: %s", file_len + 1, strerror(errno));
        fclose(file);
        return NULL;
    }
    
    if (fread(data, 1, file_len, file) != file_len) {
        printf("Read File %s Error: %s", filename, strerror(errno));
        free(data);
        fclose(file);
        return NULL;
    }

    fclose(file);

    return data;
}

// 写入文件
int __write_file(const char *filename, const char *data, size_t length)
{
    FILE *file;
	
    file = fopen(filename, "w+");
    if (file == NULL) {
        printf("Open File %s Error: %s", filename, strerror(errno));
        return -1;
    }

    if (fwrite(data, 1, length, file) != length) {
        printf("Write File %s Error: %s", filename, strerror(errno));
        fclose(file);
        return -1;
    }

    fclose(file);

    return 0;
}

time_t current_time;
const char month_tab[48] ={"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"};
const char day_tab[] = {"Sun,Mon,Tue,Wed,Thu,Fri,Sat,"};

static char* _get_commonlog_time();

char *_get_commonlog_time(void)
{
    struct tm t;
    char *p;
    unsigned int a;
    static char buf[30];
    //int time_offset;
    current_time = time(NULL);
    /* 8 hour differ from localtime. donot kown why. Hard code to CST(UT+8) timezone.*/
    current_time = current_time + 3600*8;
    /* 这里注意：
     * localtime_r是多线程安全的，所以用localtime_r替换localtime
     */
    gmtime_r(&current_time, &t);

    p = buf + 29;
    *p-- = '\0';
    *p-- = ' ';
    *p-- = ']';

    a = t.tm_sec;
    *p-- = '0' + a % 10;
    *p-- = '0' + a / 10;
    *p-- = ':';
    a = t.tm_min;
    *p-- = '0' + a % 10;
    *p-- = '0' + a / 10;
    *p-- = ':';
    a = t.tm_hour;
    *p-- = '0' + a % 10;
    *p-- = '0' + a / 10;
    *p-- = ':';
    a = 1900 + t.tm_year;
    while (a) {
        *p-- = '0' + a % 10;
        a /= 10;
    }
    /* p points to an unused spot */
    *p-- = '/';
    p -= 2;
    memcpy(p--, month_tab + 4 * (t.tm_mon), 3);
    *p-- = '/';
    a = t.tm_mday;
    *p-- = '0' + a % 10;
    *p-- = '0' + a / 10;
    *p = '[';
    
    return p;                   /* should be same as returning buf */
}

unsigned long _get_file_size(const char *path)
{
    unsigned long filesize = -1;
    struct stat statbuff;
    if(stat(path, &statbuff) < 0) {
        return filesize;
    } else {
        filesize = statbuff.st_size;
    }
    return filesize/1000;
}

void log_to_file(char* msg)
{
    char logname[256] = {"mtapp.log"};
    FILE* fp;
    /* Log size over 5M clear the content, write the log
     * unit of size is M */
    int size = _get_file_size(logname);
    if (size > 5000) {
        printf("log file size = %d\n", size);
        fp  = fopen(logname, "w+");
    } else {
        fp  = fopen(logname, "a"); 
    }
    if (fp) {
        fwrite(msg, 1, strlen(msg), fp);
        fclose(fp);
    } else{
        printf("open log file fail, erro[%d]:%s\n", errno, strerror(errno));
    } 
}

void log_mesg(const char* file, int line, const char *fmt, ...)
{
    va_list ap;
    char msg[LOG_MAX_LEN];
    sprintf(msg, "%s[%s:%d]  - ", _get_commonlog_time(), file, line);
    va_start(ap, fmt);
    vsnprintf(msg+strlen(msg), LOG_MAX_LEN-strlen(msg), fmt, ap);
    va_end(ap);
    log_to_file(msg);
    printf(msg);
}

long long __ustime(void) {
    struct timeval tv;
    long long ust;

    gettimeofday(&tv, NULL);
    ust = ((long long)tv.tv_sec) * 1000000;
    ust += tv.tv_usec;
    return ust;
}

long long __mstime(void) { return __ustime() / 1000; }

void __save_image(unsigned char* image, int width, int height, char* prefix)
{
    static int kj = 0;
    kj++;
    char name[512] = {0};
    time_t t = time(NULL) + 3600*8;
    struct tm* tm = localtime(&t);
    if (prefix) {
        sprintf(name, "%s_%02d%02d_%02d%02d%02d_%d.raw", prefix, (tm->tm_mon+1),tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, kj);
    } else {
        sprintf(name, "%02d%02d_%02d%02d%02d_%d.raw", (tm->tm_mon+1),tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, kj);
    }    
    
    FILE* fd = fopen(name, "w+");
    int nwrite = fwrite(image,1,width*height,fd);
    usleep(1); // sleep的意义？
    if (nwrite < width*height) {
        __log_mesg("Save image failed.\n");
    }
    fflush(fd);
    fclose(fd);
}
